package org.linlinjava.litemall.wx.web;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.UserAccountBinding;
import org.linlinjava.litemall.wx.annotation.LoginUser;
import org.linlinjava.litemall.wx.service.WxUserAccountBindingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/wx/account-binding")
@Validated
public class WxUserAccountBindingController {
    private final Log logger = LogFactory.getLog(WxUserAccountBindingController.class);

    @Autowired
    private WxUserAccountBindingService bindingService;

    /**
     * 创建绑定关系
     */
    @PostMapping("/bind")
    public Object createBinding(@LoginUser Integer userId,
                               @RequestBody Map<String, Object> body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        String amspUserCode = (String) body.get("amspUserCode");
        Integer amspUserId = (Integer) body.get("amspUserId");
        
        if (StringUtils.isEmpty(amspUserCode)) {
            return ResponseUtil.badArgument();
        }
        
        // 如果没有提供amspUserId，可以使用amspUserCode作为默认值或者要求必须提供
        if (amspUserId == null) {
            return ResponseUtil.fail(400, "请提供AMSP用户ID");
        }

        try {
            // 检查AMSP账号是否可以被当前用户绑定
            if (!bindingService.canAmspAccountBindToUser(amspUserCode, userId)) {
                Integer boundUserId = bindingService.getAmspAccountBoundUserId(amspUserCode);
                return ResponseUtil.fail(409, "AMSP账号 " + amspUserCode + " 已被用户 " + boundUserId + " 绑定");
            }

            // 检查是否已存在绑定关系
            if (bindingService.isBound(userId, amspUserCode)) {
                return ResponseUtil.fail(400, "账户已绑定");
            }

            UserAccountBinding binding = bindingService.createBinding(userId, amspUserCode, amspUserId);
            if (binding == null) {
                return ResponseUtil.fail(500, "创建绑定关系失败");
            }

            Map<String, Object> result = new HashMap<>();
            result.put("bindingId", binding.getId());
            result.put("status", "bound");
            result.put("message", "账户绑定成功");

            return ResponseUtil.ok(result);
        } catch (RuntimeException e) {
            return ResponseUtil.fail(400, e.getMessage());
        } catch (Exception e) {
            logger.error("创建绑定关系异常", e);
            return ResponseUtil.fail(500, "系统异常，请稍后重试");
        }
    }

    /**
     * 解绑账户
     */
    @PostMapping("/unbind")
    public Object unbindAccount(@LoginUser Integer userId,
                               @RequestBody Map<String, Object> body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        String amspUserCode = (String) body.get("amspUserCode");
        if (StringUtils.isEmpty(amspUserCode)) {
            return ResponseUtil.badArgument();
        }

        // 检查绑定关系是否存在
        if (!bindingService.isBound(userId, amspUserCode)) {
            return ResponseUtil.fail(400, "账户未绑定或绑定关系不存在");
        }

        boolean success = bindingService.unbindAccount(userId, amspUserCode);
        if (!success) {
            return ResponseUtil.fail(500, "解绑失败");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("status", "unbound");
        result.put("message", "账户解绑成功");

        return ResponseUtil.ok(result);
    }

    /**
     * 查询用户的绑定列表
     */
    @GetMapping("/list")
    public Object getUserBindings(@LoginUser Integer userId) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        List<UserAccountBinding> bindings = bindingService.getUserBindings(userId);
        if (bindings == null) {
            return ResponseUtil.fail(500, "查询绑定列表失败");
        }

        return ResponseUtil.ok(bindings);
    }

    /**
     * 查询用户的主要绑定账户
     */
    @GetMapping("/primary")
    public Object getPrimaryBinding(@LoginUser Integer userId) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        UserAccountBinding binding = bindingService.getPrimaryBinding(userId);
        if (binding == null) {
            Map<String, Object> result = new HashMap<>();
            result.put("hasPrimaryBinding", false);
            result.put("message", "用户暂无绑定账户");
            return ResponseUtil.ok(result);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("hasPrimaryBinding", true);
        result.put("binding", binding);
        return ResponseUtil.ok(result);
    }

    /**
     * 检查绑定状态
     */
    @GetMapping("/status")
    public Object checkBindingStatus(@LoginUser Integer userId,
                                   @RequestParam @NotNull String amspUserCode) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        if (StringUtils.isEmpty(amspUserCode)) {
            return ResponseUtil.badArgument();
        }

        boolean exists = bindingService.isBindingExists(userId, amspUserCode);
        boolean bound = bindingService.isBound(userId, amspUserCode);

        Map<String, Object> result = new HashMap<>();
        result.put("exists", exists);
        result.put("bound", bound);
        
        if (exists && !bound) {
            result.put("status", "pending");
            result.put("message", "绑定请求已创建，等待确认");
        } else if (bound) {
            result.put("status", "bound");
            result.put("message", "账户已绑定");
        } else {
            result.put("status", "none");
            result.put("message", "无绑定关系");
        }

        return ResponseUtil.ok(result);
    }

    /**
     * 根据AMSP用户代码查询绑定信息（供AMSP系统调用）
     */
    @GetMapping("/info")
    public Object getBindingInfo(@RequestParam @NotNull String amspUserCode) {
        if (StringUtils.isEmpty(amspUserCode)) {
            return ResponseUtil.badArgument();
        }

        UserAccountBinding binding = bindingService.getBindingByAmspUserCode(amspUserCode);
        if (binding == null) {
            Map<String, Object> result = new HashMap<>();
            result.put("bound", false);
            result.put("message", "AMSP用户代码未绑定");
            return ResponseUtil.ok(result);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("bound", true);
        result.put("litemallUserId", binding.getLitemallUserId());
        result.put("amspUserId", binding.getAmspUserId());
        result.put("bindTime", binding.getBindTime());
        return ResponseUtil.ok(result);
    }


} 